package com.gs.core.service.dao.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;

import com.gs.core.domain.Action;
import com.gs.core.domain.LoginAction;
import com.gs.core.domain.PrintAction;
import com.gs.core.service.dao.ActionDAO;
import com.gs.core.service.dao.GsHibernateDAOFacade;

@Component
public class ActionHibernateDAO extends GsHibernateDAOFacade implements ActionDAO{
	
	/**
	 * Activities done by jdbcTemplate in the call below
		1. Acquisition of the connection
		2. Participation in the transaction
		3. Execution of the statement
		4. Processing of the result set
		5. Handling any exceptions
		6. Release of the connection
	 * 
	 */
	public int getActionCount() {
	     String sql = "select count(*) from ACTION";
	     return getJdbcTemplate().queryForInt(sql);
	}	
	
	public Collection<Action> getActions(){
		String sql="select * from ACTION";
		List<Action> results = getListByRowMapper(sql); 		
		return results;
	}
	
	public Map getAction(int id){
		return getActionInfo(id);
	}
	public List getLoginActions(){
		return getActionInfoList("LOGIN");
	}
	
	public String getActionInXML(){
		String sql="select * from ACTION";
		ActionRowCallbackHandler arc = new ActionRowCallbackHandler();
		getJdbcTemplate().query(sql, arc);
		return arc.getXml();
	}
	public String getActionInJSON(){
		String sql="select * from ACTION";
		ActionRowCallbackHandler arc = new ActionRowCallbackHandler();
		getJdbcTemplate().query(sql, arc);
		return arc.getJson();
	}

	private List<Action> getListByRowMapper(String sql) {
		return getJdbcTemplate().query(sql, new ActionRowMapper());		
	}
	
	private Map getActionInfo(int id){
		String sql="select * from ACTION where action_id=?";
		return getJdbcTemplate().queryForMap(sql,id);
//		String sql="select * from ACTION where action_type=?";
//		return getJdbcTemplate().queryForMap(sql,"LOGIN"); //throws IncorrectResultSizeDataAccessException
	}
	private List getActionInfoList(String actionType){
		String sql="select * from ACTION where action_type=?";
		return getJdbcTemplate().queryForList(sql,actionType);		
	}
}

class ActionRowMapper implements RowMapper<Action>{

	public Action mapRow(ResultSet rs, int arg1) throws SQLException {
		Action a = null;
		if(rs.getString("ACTION_TYPE").equals("LOGIN")){
			String loggedInBy = rs.getString("LOGGED_IN_BY"); 
			String sourceType = rs.getString("SOURCE_TYPE");
			a = LoginAction.create(loggedInBy,sourceType);
		}else if(rs.getString("ACTION_TYPE").equals("PRINT")){
			String location = rs.getString("LOCATION");
			String deviceType = rs.getString("DEVICE_TYPE");
			a = PrintAction.create(location, deviceType);
		}
		a.setDescription(rs.getString("DESCRIPTION"));
		a.setDisplayOrder(rs.getLong("DISPLAY_ORDER"));
		a.setPerformedAt(rs.getDate("PERFORMED_AT"));
		return a;
	}
	
}

class ActionRowCallbackHandler implements RowCallbackHandler{
	String xml;
	String json;
	public void processRow(ResultSet rs) throws SQLException {
		// use xtream to xml
		// use xtream jettison driver to json
	}
	public String getXml() {
		return xml;
	}
	public String getJson() {
		return json;
	}
	
}
